package Year2013;

/**
 * 标题:幻方填空
 * 幻方是把一些数字填写在方阵中， 使得行、列、两条对角线的数字之和都相等。
 * 欧洲最著名的幻方是德国数学家、画家迪勒创作的版画《忧郁》中给出的一个4阶幻方。
 * 他把1,2,3....16这16个数字填写在4 x 4的方格中。
 * 如图p1. jpg所示，即:
 * 16  ?   ?  13
 * ？  ？  11  ?
 * 9  ？   ？  *
 * ？  15  ?   1
 *
 * 16  -0   -1  13
 * -2  -3  11  -4
 * 9  -5   -6  -7
 * -8  15 -9  1
 * 表中有些数字已经显露出来，还有些用?和*代替。
 * 请你计算出?和*所代表的数字。并把米所代表的数字作为本题答案提交。
 * 答案是一个整数，请通过浏览器直接提交该数字,
 * 注意:不要提交解答过程，或其它辅助说明类的内容。
 */
public class C组_幻方填空 {
    static int[] stack = new int[10000]; // 状态位
    static int top = 0;
    static int total = 0;
    static int[] number = {2,3,4,5,6,7,8,10,12,14};
    public static void main(String[] args) {
        fun1(0);
        System.out.println();
        System.out.println("数字为："+12);
        System.out.println(total);
    }
    public static void fun1(int n){

        if(n == 10){  // n 个元素里面选 r个元素
            if (total < 10) {
                for (int i = 0; i < 10; i++) {
                    System.out.print(stack[i] + "\t");
                }
                System.out.println();
            }
            int h1 = 16 + number[stack[0]] + number[stack[1]] + 13;
            int h2 = number[stack[2]] + number[stack[3]] + 11 + number[stack[4]];
            int h3 = 9 + number[stack[5]] + number[stack[6]] + number[stack[7]];
            int h4 = number[stack[8]] + 15 + number[stack[9]] + 1;
            int l1 = 16 + number[stack[2]] + 9 + number[stack[8]];
            int l2 = number[stack[0]] + number[stack[3]] + number[stack[5]] + 15;
            int l3 = number[stack[1]] + 11 + number[stack[6]] + number[stack[9]];
            int l4 = 13 + number[stack[4]] + number[stack[7]] + 1;
            int x1 = 13 + 11 + number[stack[5]] + number[stack[8]];
            int x2 = 16 + number[stack[3]] + number[stack[6]] + 1;
            if (h1 == h2 && h2 == h3 && h3 == h4 && h4 == l1 && l1 == l2 && l2 == l3 && l3 == l4 && l4 == x1 && x1 == x2){
                System.out.println();
                for (int i = 0; i < 10; i++) {
                    System.out.print(number[stack[i]] + "\t");
                }
            }
            total++;
            return;

        }
        for (int i = 0; i < 10; i++) {  //两个状态位，允许重复组合
            int flag = 0;
            for (int j = 0; j < top; j++) {
                if(stack[j] == i){
                    flag = 1;
                    break;
                }
            }
            if(flag == 1)
                continue;
            stack[top++] = i;
            fun1(n+1);
            top--;
        }
    }
}
